package com.bwie.service.impl;

import com.bwie.common.constants.Constants;
import com.bwie.common.constants.TokenConstants;
import com.bwie.common.domain.Order;
import com.bwie.common.domain.ResourceInfo;
import com.bwie.common.domain.User;
import com.bwie.common.domain.request.OrderListReq;
import com.bwie.common.domain.request.ResourceInfoListReq;
import com.bwie.common.exceptions.BizExceptions;
import com.bwie.common.utils.EasyPoiUtil;
import com.bwie.common.utils.JwtUtils;
import com.bwie.common.utils.StringUtils;
import com.bwie.mapper.ResourceMapper;
import com.bwie.service.ResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @className: ResourceServiceImpl
 * @Description: TODO
 * @version: v1.８.0
 * @author: 汪菲阳
 * @date: 2025/11/10 11:11
 */
@Service
public class ResourceServiceImpl implements ResourceService {
    @Autowired
    private ResourceMapper resourceMapper;
    @Autowired
    private EasyPoiUtil easyPoiUtil;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private HttpServletRequest request;

    // 线程池
    private static final ExecutorService executor = Executors.newFixedThreadPool(5);

    /**
     * 资源信息列表
     */
    @Override
    public List<ResourceInfo> infoList(ResourceInfoListReq resourceInfoListReq) {
        return resourceMapper.infoList(resourceInfoListReq);
    }

    /**
     * 订单列表--详情
     */
    @Override
    public List<Order> orderList(OrderListReq orderListReq) {
        return resourceMapper.orderList(orderListReq);
    }

    /**
     * 导入文件
     */
    @Override
    public String importFile(MultipartFile file) {
        // 生成任务ID
        String taskId = UUID.randomUUID().toString();
            // 读取Excel
            List<ResourceInfo> fileExcel = easyPoiUtil.importFileExcel(file, ResourceInfo.class);

            //判断数据是否为空
            if (CollectionUtils.isEmpty(fileExcel)) {
                throw new BizExceptions(Constants.IMPORT_IS_EMPTY_ERROR_CODE,Constants.IMPORT_IS_EMPTY_ERROR_MSG);
            }

            // 字段校验
            for (ResourceInfo info : fileExcel) {
                if (StringUtils.isEmpty(info.getTitle())) {
                    throw new BizExceptions(Constants.IMPORT_TITLE_ERROR_CODE,Constants.IMPORT_TITLE_ERROR_MSG);
                }
                if (StringUtils.isEmpty(info.getSubject())) {
                    throw new BizExceptions(Constants.IMPORT_SUBJECT_ERROR_CODE,Constants.IMPORT_SUBJECT_ERROR_MSG);
                }
                if (info.getPubYear() == null) {
                    throw new BizExceptions(Constants.IMPORT_PUB_YEAR_ERROR_CODE,Constants.IMPORT_PUB_YEAR_ERROR_MSG);
                }
            }

            // 缓存数据--存入redis
            redisTemplate.opsForValue().set(TokenConstants.PREVIEW + ":" + taskId, fileExcel, 30, TimeUnit.MINUTES);
            return taskId;
    }

    /**
     * 开始查重
     */
    @Override
    public void startDuplicateCheck(String taskId) {
        //获取导入数据
        List<ResourceInfo> importData = getImportData(taskId);

        // 异步查重
        CompletableFuture.runAsync(() -> {
           List<Map<String, Object>> results = new ArrayList<>();

           for (ResourceInfo data : importData) {
               Map<String, Object> result = new HashMap<>();
               result.put("data", data);

               // 检查题名是否重复
               List<ResourceInfo> duplicates = resourceMapper.findByTitleLike(data.getTitle());
               if (!duplicates.isEmpty()) {
                   //如果有重复的题名，则返回重复的资源
                   result.put("duplicateResources", duplicates);
               } else {
                   //如果没有重复的题名，则返回空列表
                   result.put("duplicateResources", new ArrayList<>());
               }
               //返回结果
               results.add(result);
           }
           // 存入redis
            redisTemplate.opsForValue().set(TokenConstants.DUPLICATE_RESULT + taskId, results, 30, TimeUnit.MINUTES);
        }, executor);
    }

    /**
     * 获取查重结果
     */
    @Override
    public Map<String, Object> getDuplicateResult(String taskId) {
        //从缓存中获取查重结果
        List<Map<String, Object>> results = (List<Map<String, Object>>) redisTemplate.opsForValue().get(TokenConstants.DUPLICATE_RESULT + taskId);
        Map<String, Object> result = new HashMap<>();
        //利用三目运算判断是否为空
        result.put("results", results != null ? results : new ArrayList<>());
        return result;
    }

    /**
     * 批量保存
     */
    @Override
    public void batchSave(String taskId) {
        List<ResourceInfo> importData = getImportData(taskId);
        // 设置基本信息
        User user = getCurrentUser();
        Date now = new Date();

        for (ResourceInfo info : importData) {
            info.setUpdTime(now);
            info.setUserId(user.getID());
            info.setOrderStatus(0);
            info.setInlet(1);
        }
        // 批量保存
        resourceMapper.batchInsert(importData);
        // 清理缓存
        redisTemplate.delete(TokenConstants.PREVIEW + ":" + taskId);
        redisTemplate.delete(TokenConstants.DUPLICATE_RESULT + taskId);
    }

    /**
     * 取消导入
     */
    @Override
    public void cancelImport(String taskId) {
        redisTemplate.delete(TokenConstants.PREVIEW + ":" + taskId);
        redisTemplate.delete(TokenConstants.DUPLICATE_RESULT + taskId);
    }

    /**
     * 预览列表
     */
    @Override
    public List<ResourceInfo> previewList(ResourceInfoListReq resourceInfoListReq) {
        Set<String> keys = redisTemplate.keys(TokenConstants.PREVIEW + ":*");
        if (!CollectionUtils.isEmpty(keys)) {
            return (List<ResourceInfo>) redisTemplate.opsForValue().get(keys.iterator().next());
        }
        return new ArrayList<>();
    }

    /**
     * 获取查重进度
     */
    @Override
    public Map<String, Object> getDuplicateProgress(String taskId) {
        Map<String, Object> progress = new HashMap<>();
        progress.put("status", "completed");
        //返回进度
        return progress;
    }

    /**
     * 获取导入数据
     */
    private List<ResourceInfo> getImportData(String taskId) {
        List<ResourceInfo> data = (List<ResourceInfo>) redisTemplate.opsForValue().get(TokenConstants.PREVIEW + ":" + taskId);
        if (CollectionUtils.isEmpty(data)) {
            throw new BizExceptions("导入数据不存在或已过期");
        }
        return data;
    }

    /**
     * 获取当前用户
     */
    private User getCurrentUser() {
        String token = request.getHeader(TokenConstants.TOKEN);
        if (token == null) {
            throw new BizExceptions(Constants.USER_IS__NULL_CODE, Constants.USER_IS__NULL_MSG);
        }
        String userKey = JwtUtils.getUserKey(token);
        return (User) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
    }
}